#include "rttJtagGPIO.h"

#include <rtthread.h>
#include <rtdevice.h>
#include <string.h>
#include <stdio.h>

rttJtagGPIO::rttJtagGPIO()
{
    memset(&pins, 0xff, sizeof(pins));
}

bool rttJtagGPIO::open(const char *dev)
{
    uint32_t len;
    char *pin;
    char *name;
    char tmp[16];
    int start;

    if (!dev)
        return false;

    len = strlen(dev);
    for (int i = 0, start = 0; i <= len; i++)
    {
        if ((dev[i] != ',') && (dev[i] != '\0'))
            continue;

        tmp[0] = 0;
        strncat(tmp, &dev[start], i - start);
        start = i + 1;
        pin = tmp;
        name = tmp;
        while (*name)
        {
            if (*name == ':')
            {
                *name = 0;
                name++;
                break;
            }

            name++;
        }

        if (strcmp(pin, "tdi") == 0)
        {
            this->pins.tdi = rt_pin_get(name);
            continue;
        }
        if (strcmp(pin, "tdo") == 0)
        {
            this->pins.tdo = rt_pin_get(name);
            continue;
        }
        if (strcmp(pin, "tck") == 0)
        {
            this->pins.tck = rt_pin_get(name);
            continue;
        }
        if (strcmp(pin, "tms") == 0)
        {
            this->pins.tms = rt_pin_get(name);
            continue;
        }
        if (strcmp(pin, "trs") == 0)
        {
            this->pins.trs = rt_pin_get(name);
            continue;
        }
        if (strcmp(pin, "srs") == 0)
        {
            this->pins.srs = rt_pin_get(name);
            continue;
        }
    }

    if (this->pins.tdi == -1 || this->pins.tdo == -1 || this->pins.tck == -1 || this->pins.tms == -1)
        return false;

    rt_pin_mode(this->pins.tdi, PIN_MODE_OUTPUT);
    rt_pin_mode(this->pins.tdo, PIN_MODE_INPUT);
    rt_pin_mode(this->pins.tck, PIN_MODE_OUTPUT);
    rt_pin_mode(this->pins.tms, PIN_MODE_OUTPUT);

    if (this->pins.trs >= 0)
    {
        rt_pin_mode(this->pins.trs, PIN_MODE_OUTPUT);
        rt_pin_write(this->pins.trs, 1);
    }
    if (this->pins.srs >= 0)
    {
        rt_pin_mode(this->pins.srs, PIN_MODE_OUTPUT);
        rt_pin_write(this->pins.srs, 1);
    }
    if (this->pins.led >= 0)
    {
        rt_pin_mode(this->pins.led, PIN_MODE_OUTPUT);
        rt_pin_write(this->pins.led, 1);
    }

    return true;
}

void rttJtagGPIO::close()
{
}

int rttJtagGPIO::tdo_read()
{
    return rt_pin_read(this->pins.tdo);
}

int rttJtagGPIO::ttt_write(int tck, int tms, int tdi)
{
    rt_pin_write(this->pins.tdi, tdi);
    rt_pin_write(this->pins.tms, tms);
    rt_pin_write(this->pins.tck, tck);

    return 0;
}

void rttJtagGPIO::reset(int trst, int srst)
{
    if (this->pins.trs >= 0)
        rt_pin_write(this->pins.trs, trst);
    if (this->pins.trs >= 0)
        rt_pin_write(this->pins.srs, srst);
}

void rttJtagGPIO::blink(int on)
{
    if (this->pins.led < 0)
        return;

    rt_pin_write(this->pins.led, on);
}
